package com.laopan.elasticsearch.handler;

import com.laopan.elasticsearch.bean.Field;
import com.laopan.elasticsearch.bean.Page;
import com.laopan.elasticsearch.bean.QueryResult;
import com.laopan.elasticsearch.core.Query;
import com.laopan.elasticsearch.utils.JsonUtils;
import org.apache.lucene.search.TotalHits;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;

import java.util.ArrayList;
import java.util.List;

/**
 * <p>
 *
 * </p>
 *
 * @author laopan
 * @className AbstractQuery
 * @date 2021/4/21 9:57
 */

public abstract class AbstractQuery<T> extends AbstractIndexInfo {

    private Query query;

    public AbstractQuery(Query query) {
        this.query = query;
    }

    public Query getQuery() {
        return query;
    }

    public void setQuery(Query query) {
        this.query = query;
    }

    public T queryById(String id) {
        SearchResponse resp = query.idQuery(getIndex(),id);
        List<T> result = getResult(resp);
        if (!result.isEmpty()) {
            return result.get(0);
        }
        return null;
    }
    public QueryResult<T> queryByField(Field field) {
        return queryByField(field,null);
    }
    public QueryResult<T> queryByField(Field field, Page page) {
        SearchResponse resp = query.termQuery(getIndex(),field,page);
        return convertData(resp);
    }
    public QueryResult<T> queryByMultiField(List<Field> field) {
        return queryByMultiField(field,null);
    }
    public QueryResult<T> queryByMultiField(List<Field> field,Page page) {
        SearchResponse resp = query.multiTermQuery(getIndex(),field,page);
        return convertData(resp);
    }
    public QueryResult<T> convertData(SearchResponse resp) {
        if (null != resp) {
            SearchHits searchHits = resp.getHits();
            if (null != searchHits) {
                TotalHits totalHits = searchHits.getTotalHits();
                List<T> dataList = getResult(resp);
                return new QueryResult<>(totalHits.value, dataList);
            }
        }
        return new QueryResult<>(0L,new ArrayList<>());
    }
    public  List<T> getResult(SearchResponse resp){
        if (null == resp || null == resp.getHits()) {
            return new ArrayList<>();
        }
        SearchHits searchHits = resp.getHits();
        SearchHit[] hits = searchHits.getHits();
        List<T> dataList = new ArrayList<>();
        T data;
        if (null != hits && hits.length > 0) {
            for (SearchHit hit : hits) {
                data = JsonUtils.fromJson(hit.getSourceAsString(), getEntityClass());
                dataList.add(data);
            }
        }
        return dataList;
    }

    /**
     * 获取返回的实体类对象
     * @return
     */
    public abstract Class<T> getEntityClass();

}
